www.gusucode.com > VC++ 打飞机游戏-源码程序 > VC++ 打飞机游戏-源码程序\code\src\FighterDlg.cpp

    // FighterDlg.cpp : implementation file
// Download by http://www.codefans.net

#include "stdafx.h"
#include "Fighter.h"
#include "mmsystem.h"
#include "FighterDlg.h"
#include "FighterInfo.h"
#include "CongraduationDlg.h"
#include "AboutPage.h"
#include "RankPage.h"
#include "SettingPage.h"
#include "OperationPage.h"
#include "BCMenu.h"
#include "QuitDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

HRGN BitmapToRegion(HBITMAP hBmp, COLORREF cTransparentColor = 0, COLORREF cTolerance = 0x101010);

/*/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
*/
/////////////////////////////////////////////////////////////////////////////
// CFighterDlg dialog

CFighterDlg::CFighterDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CFighterDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFighterDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_pPic = NULL;
//	m_pOldBitmap = NULL;
	m_bShowHandCursor = FALSE;
	m_bShowShootingCursor = FALSE;
	m_bLoadFrame = FALSE;
	m_bLoadWelcomeString = TRUE;
	m_bSound = TRUE;
	m_bByComputer = TRUE;
	m_bShow = TRUE;

	m_nFighterDown = 0;
	m_nFighterHit = 0;
	m_nBomb = 0;

	for(int i=0; i<10; i++)
		for(int j=0; j<10; j++)
		{
			m_nSky[i][j] = 0;
			m_nShootingResult[i][j] = 0;
		}

	m_rectSky = CRect(70, 54, 70+300, 54+300);

	m_ptNew = CPoint(m_rectSky.right+10, m_rectSky.top);

	m_rectCommentFrame = CRect(m_rectSky.right+20, m_rectSky.top+100, m_rectSky.right+132, m_rectSky.top+172);
	m_ptComment = CPoint(m_rectCommentFrame.left, m_rectCommentFrame.top);

	m_rectFighterDown = CRect(m_rectSky.right+20, m_rectCommentFrame.bottom+40, m_rectCommentFrame.right, m_rectCommentFrame.bottom+55);
	m_rectBomb = CRect(m_rectSky.right+20, m_rectCommentFrame.bottom+70, m_rectCommentFrame.right, m_rectCommentFrame.bottom+85);
	m_rectFighterHit = CRect(m_rectSky.right+20, m_rectCommentFrame.bottom+100, m_rectCommentFrame.right, m_rectCommentFrame.bottom+115);

	m_nCommentTimer = 0;
	m_nWelcomeTimer = 0;

	m_strComment5 = "";
	m_strComment4 = "";
	m_strComment3 = "";
	m_strComment2 = "";
	m_strComment1 = "";

	m_nGameStatus = FIGHTER_STOP;
}

CFighterDlg::~CFighterDlg()
{
//	if(m_pOldBitmap)
//	{
//		memDC.SelectObject(m_pOldBitmap);
//		m_FrameBitmap.DeleteObject();
//	}
}

void CFighterDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFighterDlg)
	DDX_Control(pDX, IDC_BUTTON_LOAD, m_ctrlLoad);
	DDX_Control(pDX, IDC_BUTTON_SAVE, m_ctrlSave);
	DDX_Control(pDX, IDC_BUTTON_QUIT, m_ctrlQuit);
	DDX_Control(pDX, IDC_BUTTON_OPTION, m_ctrlOption);
	DDX_Control(pDX, IDC_BUTTON_POSITION, m_ctrlPosition);
	DDX_Control(pDX, IDC_BUTTON_NEW, m_ctrlNew);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CFighterDlg, CDialog)
	//{{AFX_MSG_MAP(CFighterDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_SETCURSOR()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_RBUTTONDOWN()
	ON_WM_TIMER()
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_MENU_SHOW, OnMenuShow)
	ON_WM_DESTROY()
	ON_COMMAND(ID_MENU_LOAD, OnMenuLoad)
	ON_COMMAND(ID_MENU_QUIT, OnMenuQuit)
	ON_COMMAND(ID_MENU_SAVE, OnMenuSave)
	ON_COMMAND(ID_MENU_SOUND, OnMenuSound)
	ON_BN_CLICKED(IDC_BUTTON_NEW, OnButtonNew)
	ON_BN_CLICKED(IDC_BUTTON_LOAD, OnButtonLoad)
	ON_BN_CLICKED(IDC_BUTTON_OPTION, OnButtonOption)
	ON_BN_CLICKED(IDC_BUTTON_POSITION, OnButtonPosition)
	ON_BN_CLICKED(IDC_BUTTON_QUIT, OnButtonQuit)
	ON_BN_CLICKED(IDC_BUTTON_SAVE, OnButtonSave)
	ON_COMMAND(ID_MENU_HOMEPAGE, OnMenuHomepage)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_CLICK_TRAYICON,OnClickTrayIcon)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFighterDlg message handlers

BOOL CFighterDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	ModifyStyle(WS_CAPTION, 0);

//	if (m_ctrlFrame.Load(MAKEINTRESOURCE(IDR_GIF_FRAME),_T("Gif")))
//		m_ctrlFrame.Draw();	

	m_ctrlNew.SetMyBitmap(IDB_NEW);
//	m_ctrlNew.SetBitmap((HBITMAP)m_bmpNew);
	m_ctrlNew.MoveWindow(m_ptNew.x, m_ptNew.y, 60, 25, SWP_NOZORDER| SWP_NOMOVE);

	m_ctrlPosition.SetMyBitmap(IDB_POSITION);
//	m_ctrlPosition.SetBitmap((HBITMAP)m_bmpPosition);
	m_ctrlPosition.MoveWindow(m_ptNew.x+BUTTON_INTERVAL_H, m_ptNew.y, 60, 25, SWP_NOZORDER| SWP_NOMOVE);

	m_ctrlSave.SetMyBitmap(IDB_SAVE);
//	m_ctrlSave.SetBitmap((HBITMAP)m_bmpSave);
	m_ctrlSave.MoveWindow(m_ptNew.x, m_ptNew.y+BUTTON_INTERVAL_V, 60, 25, SWP_NOZORDER| SWP_NOMOVE);

	m_ctrlOption.SetMyBitmap(IDB_OPTION);
//	m_ctrlOption.SetBitmap((HBITMAP)m_bmpOption);
	m_ctrlOption.MoveWindow(m_ptNew.x+BUTTON_INTERVAL_H, m_ptNew.y+BUTTON_INTERVAL_V, 60, 25, SWP_NOZORDER| SWP_NOMOVE);

	m_ctrlQuit.SetMyBitmap(IDB_QUIT);
//	m_ctrlQuit.SetBitmap((HBITMAP)m_bmpQuit);
	m_ctrlQuit.MoveWindow(m_ptNew.x+BUTTON_INTERVAL_H, m_ptNew.y+BUTTON_INTERVAL_V*2, 60, 25, SWP_NOZORDER| SWP_NOMOVE);

	m_ctrlLoad.SetMyBitmap(IDB_LOAD);
//	m_ctrlLoad.SetBitmap((HBITMAP)m_bmpLoad);
	m_ctrlLoad.MoveWindow(m_ptNew.x, m_ptNew.y+BUTTON_INTERVAL_V*2, 60, 25, SWP_NOZORDER| SWP_NOMOVE);

	CBitmap bmpMask;
	bmpMask.LoadBitmap(IDB_FRAME);
	HRGN hRgn;
	hRgn = ::BitmapToRegion((HBITMAP)bmpMask, RGB(0, 0, 0));//??ȡ??????״
	SetWindowRgn(hRgn, TRUE);//??????Ļ??״
	::DeleteObject(hRgn);
	bmpMask.DeleteObject();

//	m_bmpFrame.LoadBitmap(IDB_FRAME);

//	LoadJPG("frame.jpg");
/*	if(LoadJPG("frame.gif"))
	{
		DrawBackground();
		m_bLoadFrame = TRUE;
	}
	else
	{
		m_bLoadFrame = FALSE;
		PostMessage(WM_CLOSE);
		return FALSE;
	}
*/
	m_hNewCursor = LoadCursorFromFile("shooting.ani");
//	m_hOldCursor = (HCURSOR)GetClassLong(GetSafeHwnd(), GCL_HCURSOR);

	m_nWelcomeTimer = SetTimer(FIGHTER_WELCOME_TIMER, FIGHTER_SCRROLTIME, NULL);

	
	m_ctrlNew.GetWindowRect(&m_rectNew);
	ScreenToClient(&m_rectNew);
	m_ctrlPosition.GetWindowRect(&m_rectPosition);
	ScreenToClient(&m_rectPosition);
	m_ctrlSave.GetWindowRect(&m_rectSave);
	ScreenToClient(&m_rectSave);
	m_ctrlOption.GetWindowRect(&m_rectOption);
	ScreenToClient(&m_rectOption);
	m_ctrlLoad.GetWindowRect(&m_rectLoad);
	ScreenToClient(&m_rectLoad);
	m_ctrlQuit.GetWindowRect(&m_rectQuit);
	ScreenToClient(&m_rectQuit);

	char pathname[_MAX_PATH];
	char drive[_MAX_DRIVE];
	char dir[_MAX_DIR];
	char fname[_MAX_FNAME];
	char ext[_MAX_EXT];

	GetModuleFileName(NULL, pathname, _MAX_PATH);
	_splitpath(pathname, drive, dir, fname, ext);
	m_strBossFile.Format("%s%sSetting.txt", drive, dir);

	NOTIFYICONDATA tnd;	
	
	tnd.cbSize=sizeof(NOTIFYICONDATA);
	tnd.hWnd=this->m_hWnd;
	tnd.uID=IDR_MAINFRAME;
	tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
	tnd.uCallbackMessage=WM_CLICK_TRAYICON;
	tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
	strcpy(tnd.szTip,"??ɻ?");
	
	Shell_NotifyIcon(NIM_ADD,&tnd);

	if(!ReadRankFile(&m_TopTen))
	{
		for(int i=0; i<10; i++)
		{
			sprintf(m_TopTen.name[i], "NULL");
			m_TopTen.bomb[i] = 0; //???
			m_TopTen.hitpercentage[i] = 0;
		}
		if(!WriteRankFile(m_TopTen))
		{
			AfxMessageBox("????д?????ļ?(fighter.rnk)");
			PostMessage(WM_CLOSE);
			return FALSE;
		}
	}

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CFighterDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CPropertySheet Sheet("ѡ??", this, 3);

		CRankPage rankPage;
		for(int i=0; i<10; i++)
		{
			rankPage.m_fHitPercentage[i] = m_TopTen.hitpercentage[i];
			rankPage.m_nBomb[i] = m_TopTen.bomb[i];
			sprintf(rankPage.m_strName[i], "%s", m_TopTen.name[i]);
		}

		COperationPage operationPage;
		CAboutPage aboutPage;
		CSettingPage settingPage;
		settingPage.m_strBossFile = m_strBossFile;

		Sheet.m_psh.dwFlags &= ~PSH_HASHELP;
		Sheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;

		Sheet.AddPage(&settingPage);
		Sheet.AddPage(&rankPage);
		Sheet.AddPage(&operationPage);
		Sheet.AddPage(&aboutPage);

		if(Sheet.DoModal()==IDOK)
		{
			m_strBossFile = settingPage.m_strBossFile;
			m_bSound = settingPage.m_bSound;

			if(settingPage.m_bShortcut)
			{
				CString strShortcutText;
				strShortcutText = settingPage.m_strShortcutName;

				char pathname[_MAX_PATH];
				GetModuleFileName(NULL, pathname, _MAX_PATH);//??ִ???ļ?????Ŀ¼

				char winpath[_MAX_PATH];
				::GetWindowsDirectory(winpath, _MAX_PATH);
				CString destPath = winpath;
				destPath += "\\Desktop\\";
				destPath += (strShortcutText.Right(4)==".lnk")?(strShortcutText):(strShortcutText+".lnk");

				FileLink(pathname, (LPCTSTR)destPath);
			}
		}
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CFighterDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CPaintDC dc(this); // device context for painting
//		CDC memDC;
//		memDC.CreateCompatibleDC(&dc);
//	CClientDC dc(this);
		m_memDC.CreateCompatibleDC(&dc);


		CBitmap bmpFrame;
		bmpFrame.LoadBitmap(IDB_FRAME);

		CBitmap *pOldBmp;
		pOldBmp = m_memDC.SelectObject(&bmpFrame);

		CFont textFont;
		CFont* pOldFont;
		textFont.CreateFont(MulDiv(10, -dc.GetDeviceCaps(LOGPIXELSY), 72), 
			0, 0, 0, FW_THIN, FALSE, FALSE, 0,
			DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
			DEFAULT_QUALITY, DEFAULT_PITCH|FF_SWISS, _T("????"));
		pOldFont=(CFont*)m_memDC.SelectObject(&textFont);

		//??ʾ???
		CBrush whiteBrush(RGB(255,255,255));
		m_memDC.FillRect(m_rectFighterHit, &whiteBrush);
		m_memDC.FillRect(m_rectFighterDown, &whiteBrush);
		m_memDC.FillRect(m_rectBomb, &whiteBrush);
		CString sTemp;
		sTemp.Format("???зɻ???%3d ??", m_nFighterHit);
		m_memDC.TextOut(m_rectFighterHit.left, m_rectFighterHit.top, sTemp);
		sTemp.Format("????ɻ???%3d ??", m_nFighterDown);
		m_memDC.TextOut(m_rectFighterDown.left, m_rectFighterDown.top, sTemp);
		sTemp.Format("?ѷ??ڵ???%3d ??", m_nBomb);
		m_memDC.TextOut(m_rectBomb.left, m_rectBomb.top, sTemp);

		// ??ʾ??Ϣ?Ŀ??
		CBrush brush(RGB(132, 132, 132));
		m_memDC.FillRect(m_rectCommentFrame, &brush);

		CPen penDarkGray(PS_SOLID, 2, RGB(72, 72, 72));
		CPen *pOldPen;
		pOldPen = m_memDC.SelectObject(&penDarkGray);
		m_memDC.MoveTo(m_rectCommentFrame.left, m_rectCommentFrame.bottom);
		m_memDC.LineTo(m_rectCommentFrame.left, m_rectCommentFrame.top);
		m_memDC.LineTo(m_rectCommentFrame.right, m_rectCommentFrame.top);
		CPen penLightGray(PS_SOLID, 2, RGB(192, 192, 192));
		m_memDC.SelectObject(&penLightGray);
		m_memDC.MoveTo(m_rectCommentFrame.right, m_rectCommentFrame.top);
		m_memDC.LineTo(m_rectCommentFrame.right, m_rectCommentFrame.bottom);
		m_memDC.LineTo(m_rectCommentFrame.left, m_rectCommentFrame.bottom);
		m_memDC.SelectObject(pOldPen);

		//??ʾ????
		DrawComment(&m_memDC);

		//??ʾ??յĽ??
		DrawShootingResult(&m_memDC);
		
		dc.BitBlt(0, 0, 545, 409, &m_memDC, 0, 0, SRCCOPY);

		m_memDC.SelectObject(pOldPen);
		m_memDC.SelectObject(pOldBmp);
		m_memDC.SelectObject(pOldFont);

		bmpFrame.DeleteObject();
		textFont.DeleteObject();

		m_memDC.DeleteDC();
	/*	LONG nPaintWidth = m_PaintRect.right-m_PaintRect.left;

		if (nPaintWidth > 0)
		{
			LONG nPaintHeight = m_PaintRect.bottom - m_PaintRect.top;
			::BitBlt(dc.m_hDC, 0, 0, nPaintWidth, nPaintHeight,	
				m_hm_memDC, m_PaintRect.left, m_PaintRect.top, SRCCOPY);
		}
		else*/
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CFighterDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

//
//	BitmapToRegion :	create a region from the "non-transparent" pixels of a bitmap
//	author :   Jean-Edouard Lachand-Robert (http://www.geocities.com/paris/leftbank/1160/resume.htm), june 1998.
//                E-mail: iamwired@geocities.com
//	hbmp :		source bitmap
//	cTransparentColor :	color base for the "transparent" pixels (default is black)
//	cTolerance :		color tolerance for the "transparent" pixels.
//	a pixel is assumed to be transparent if the value of each of its 3 components (blue, green and red) is 
//	greater or equal to the corresponding value in cTransparentColor and is lower or equal to the 
//	corresponding value in cTransparentColor + cTolerance.
HRGN BitmapToRegion(HBITMAP hBmp, COLORREF cTransparentColor, COLORREF cTolerance)
{
	HRGN hRgn = NULL;

	if (hBmp)
	{
		// Create a memory DC inside which we will scan the bitmap content
		HDC hMemDC = CreateCompatibleDC(NULL);
		if (hMemDC)
		{
			// Get bitmap size
			BITMAP bm;
			GetObject(hBmp, sizeof(bm), &bm);

			// Create a 32 bits depth bitmap and select it into the memory DC 
			BITMAPINFOHEADER RGB32BITSBITMAPINFO = {
					sizeof(BITMAPINFOHEADER),	// biSize 
					bm.bmWidth,					// biWidth; 
					bm.bmHeight,				// biHeight; 
					1,							// biPlanes; 
					32,							// biBitCount 
					BI_RGB,						// biCompression; 
					0,							// biSizeImage; 
					0,							// biXPelsPerMeter; 
					0,							// biYPelsPerMeter; 
					0,							// biClrUsed; 
					0							// biClrImportant; 
			};
			VOID * pbits32; 
			HBITMAP hbm32 = CreateDIBSection(hMemDC,
				(BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
			if (hbm32)
			{
				HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);

				// Create a DC just to copy the bitmap into the memory DC
				HDC hDC = CreateCompatibleDC(hMemDC);
				if (hDC)
				{
					// Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits)
					BITMAP bm32;
					GetObject(hbm32, sizeof(bm32), &bm32);
					while (bm32.bmWidthBytes % 4)
						bm32.bmWidthBytes++;

					// Copy the bitmap into the memory DC
					HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
					BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);

					// For better performances, we will use the ExtCreateRegion() function to create the
					// region. This function take a RGNDATA structure on entry. We will add rectangles by
					// amount of ALLOC_UNIT number in this structure.
					#define ALLOC_UNIT	100
					DWORD maxRects = ALLOC_UNIT;
					HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
					RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
					pData->rdh.dwSize = sizeof(RGNDATAHEADER);
					pData->rdh.iType = RDH_RECTANGLES;
					pData->rdh.nCount = pData->rdh.nRgnSize = 0;
					SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);

					// Keep on hand highest and lowest values for the "transparent" pixels
					BYTE lr = GetRValue(cTransparentColor);
					BYTE lg = GetGValue(cTransparentColor);
					BYTE lb = GetBValue(cTransparentColor);
					BYTE hr = min(0xff, lr + GetRValue(cTolerance));
					BYTE hg = min(0xff, lg + GetGValue(cTolerance));
					BYTE hb = min(0xff, lb + GetBValue(cTolerance));

					// Scan each bitmap row from bottom to top (the bitmap is inverted vertically)
					BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
					for (int y = 0; y < bm.bmHeight; y++)
					{
						// Scan each bitmap pixel from left to right
						for (int x = 0; x < bm.bmWidth; x++)
						{
							// Search for a continuous range of "non transparent pixels"
							int x0 = x;
							LONG *p = (LONG *)p32 + x;
							while (x < bm.bmWidth)
							{
								BYTE b = GetRValue(*p);
								if (b >= lr && b <= hr)
								{
									b = GetGValue(*p);
									if (b >= lg && b <= hg)
									{
										b = GetBValue(*p);
										if (b >= lb && b <= hb)
											// This pixel is "transparent"
											break;
									}
								}
								p++;
								x++;
							}

							if (x > x0)
							{
								// Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region
								if (pData->rdh.nCount >= maxRects)
								{
									GlobalUnlock(hData);
									maxRects += ALLOC_UNIT;
									hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
									pData = (RGNDATA *)GlobalLock(hData);
								}
								RECT *pr = (RECT *)&pData->Buffer;
								SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
								if (x0 < pData->rdh.rcBound.left)
									pData->rdh.rcBound.left = x0;
								if (y < pData->rdh.rcBound.top)
									pData->rdh.rcBound.top = y;
								if (x > pData->rdh.rcBound.right)
									pData->rdh.rcBound.right = x;
								if (y+1 > pData->rdh.rcBound.bottom)
									pData->rdh.rcBound.bottom = y+1;
								pData->rdh.nCount++;

								// On Windows98, ExtCreateRegion() may fail if the number of rectangles is too
								// large (ie: > 4000). Therefore, we have to create the region by multiple steps.
								if (pData->rdh.nCount == 2000)
								{
									HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
									if (hRgn)
									{
										CombineRgn(hRgn, hRgn, h, RGN_OR);
										DeleteObject(h);
									}
									else
										hRgn = h;
									pData->rdh.nCount = 0;
									SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
								}
							}
						}

						// Go to next row (remember, the bitmap is inverted vertically)
						p32 -= bm32.bmWidthBytes;
					}

					// Create or extend the region with the remaining rectangles
					HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
					if (hRgn)
					{
						CombineRgn(hRgn, hRgn, h, RGN_OR);
						DeleteObject(h);
					}
					else
						hRgn = h;

					// Clean up
					GlobalFree(hData);
					SelectObject(hDC, holdBmp);
					DeleteDC(hDC);
				}

				DeleteObject(SelectObject(hMemDC, holdBmp));
			}

			DeleteDC(hMemDC);
		}
	}

	return hRgn;
}

void CFighterDlg::OnOK() 
{
	// TODO: Add extra validation here
//	return;
	CDialog::OnOK();
}

void CFighterDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
//	if(MessageBox("Do you really want to quit?", "Fighter Message", MB_YESNO)==IDNO)
//		return ;
	if(m_nWelcomeTimer!=0)
		KillTimer(m_nWelcomeTimer);
	if(m_nCommentTimer!=0)
		KillTimer(m_nCommentTimer);

	CDialog::OnCancel();
}

void CFighterDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	PostMessage (WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM (point.x, point.y));

/*	if(m_rectNew.PtInRect(point))
	{
		OnClickNew();
		return;
	}
	
	if(m_rectPosition.PtInRect(point))
	{
		OnClickPosition();
		return;
	}
	
	if(m_rectSave.PtInRect(point))
	{
		OnClickSave();
		return;
	}

	if(m_rectOption.PtInRect(point))
	{
		OnClickOption();
		return;
	}

	if(m_rectLoad.PtInRect(point))
	{
		OnClickLoad();
		return;
	}

	if(m_rectQuit.PtInRect(point))
	{
		OnClickQuit();
		return;
	}
*/
	if(!m_rectSky.PtInRect(point)||m_nGameStatus==FIGHTER_STOP)
		return;

	CPoint ptShootingAt = CPoint((point.x-m_rectSky.left)/PIECE_SIDE,
		(point.y-m_rectSky.top)/PIECE_SIDE);

	switch(m_nShootingResult[ptShootingAt.x][ptShootingAt.y])
	{
	case FIGHTER_UNEXPLORE:
	case FIGHTER_GUESS_HITNULL:
		m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_GUESS_HIT;
		InvalidateRect(
			CRect(m_rectSky.left+ptShootingAt.x*PIECE_SIDE+1,
			m_rectSky.top+ptShootingAt.y*PIECE_SIDE+1,
			m_rectSky.left+(ptShootingAt.x+1)*PIECE_SIDE-1,
			m_rectSky.top +(ptShootingAt.y+1)*PIECE_SIDE-1), TRUE);
		break;
	case FIGHTER_GUESS_HIT:
		m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_UNEXPLORE;
		InvalidateRect(
			CRect(m_rectSky.left+ptShootingAt.x*PIECE_SIDE+1,
			m_rectSky.top+ptShootingAt.y*PIECE_SIDE+1,
			m_rectSky.left+(ptShootingAt.x+1)*PIECE_SIDE-1,
			m_rectSky.top +(ptShootingAt.y+1)*PIECE_SIDE-1), TRUE);
		break;
	case FIGHTER_HITDOWN:
	case FIGHTER_HIT:
	case FIGHTER_HITNULL:
		break;
	case FIGHTER_POSITION_NULL:
	case FIGHTER_POSITION_BODY://????????ǿջ???????򵥻??????ʾ?˸?Ϊ??ͷ
		m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_POSITION_HEADER;
		InvalidateRect(
			CRect(m_rectSky.left+ptShootingAt.x*PIECE_SIDE+1,
			m_rectSky.top+ptShootingAt.y*PIECE_SIDE+1,
			m_rectSky.left+(ptShootingAt.x+1)*PIECE_SIDE-1,
			m_rectSky.top +(ptShootingAt.y+1)*PIECE_SIDE-1), TRUE);
		break;
	case FIGHTER_POSITION_HEADER://????ʱ????Ѿ???ͷ?ˣ??????
		m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_POSITION_NULL;
		InvalidateRect(
			CRect(m_rectSky.left+ptShootingAt.x*PIECE_SIDE+1,
			m_rectSky.top+ptShootingAt.y*PIECE_SIDE+1,
			m_rectSky.left+(ptShootingAt.x+1)*PIECE_SIDE-1,
			m_rectSky.top +(ptShootingAt.y+1)*PIECE_SIDE-1), TRUE);
		break;
	default:
		break;
	}

//	CDialog::OnLButtonDown(nFlags, point);
}
/*
void CFighterDlg::DrawBackground()
{
	if(m_pPic==NULL)
		return;
	OLE_XSIZE_HIMETRIC hmWidth; 
	OLE_YSIZE_HIMETRIC hmHeight; 
	
	m_pPic->get_Width(&hmWidth); 
	m_pPic->get_Height(&hmHeight); 
	
	double fX,fY; 

	fX = (double)memDC.GetDeviceCaps(HORZRES)*(double)hmWidth/((double)memDC.GetDeviceCaps(HORZSIZE)*100.0); 
	fY = (double)memDC.GetDeviceCaps(VERTRES)*(double)hmHeight/((double)memDC.GetDeviceCaps(VERTSIZE)*100.0); 
	if(FAILED(m_pPic->Render(memDC.GetSafeHdc(),0,0,m_szPicture.cx,m_szPicture.cy,0,hmHeight,hmWidth,-hmHeight,NULL))) 
		AfxMessageBox("Failed To Render The picture!"); 
//	pPic->Release(); 
}

BOOL CFighterDlg::LoadBackground(LPCTSTR strFileName)
{
	IStream *pStm; 

	CFileStatus fstatus; 
	CFile file; 
	LONG cb; 
	CString strFile = strFileName;

	if(file.Open((LPCTSTR)strFile,CFile::modeRead)==FALSE)
	{
		if(MessageBox("frame.gif not found in current directory. It is neccesary and do you want to select one(545*409)?",
			"Fighter Message", MB_YESNO)==IDNO)
			return FALSE;

		CFileDialog dlgFile(TRUE, _T("*.gif"), NULL,
			OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
			_T("Gif Files (*.gif)|*.gif||"));
		if (dlgFile.DoModal() == IDCANCEL)
			return FALSE;
		strFile = dlgFile.GetPathName();
		if(file.Open((LPCTSTR)strFile, CFile::modeRead)==FALSE)
			return FALSE;
	}

	if (file.GetStatus((LPCTSTR)strFile, fstatus)
		&& ((cb = fstatus.m_size) != -1))
	{ 
		HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb); 
		LPVOID pvData = NULL; 
		if (hGlobal != NULL) 
		{ 
			if ((pvData = GlobalLock(hGlobal)) != NULL) 
			{ 
				file.ReadHuge(pvData, cb); 
				GlobalUnlock(hGlobal); 
				CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); 
				
				if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&m_pPic)))
				{
					long hmWidth;
					long hmHeight;
					m_pPic->get_Width(&hmWidth);
					m_pPic->get_Height(&hmHeight);

					CDC *pDC = GetDC();
					m_szPicture.cx = MulDiv(hmWidth, pDC->GetDeviceCaps(LOGPIXELSX), 2540);
					m_szPicture.cy = MulDiv(hmHeight, pDC->GetDeviceCaps(LOGPIXELSY), 2540);

					if(!memDC.CreateCompatibleDC(pDC))
					{
						ReleaseDC(pDC);
						return FALSE;
					};

					if(!m_FrameBitmap.CreateCompatibleBitmap(pDC,m_szPicture.cx,m_szPicture.cy))
					{
						ReleaseDC(pDC);
						memDC.DeleteDC();
						return FALSE;
					};

					m_pOldBitmap = memDC.SelectObject(&m_FrameBitmap);

//					m_clrBackground = GetSysColor(COLOR_3DFACE);

					RECT rect = {0,0,m_szPicture.cx,m_szPicture.cy};
					memDC.FillRect(&rect,CBrush::FromHandle((HBRUSH)(COLOR_WINDOW)));

					ReleaseDC(pDC);

					return TRUE; 
				}
			}
		}
	}

	return FALSE;
}
*/
BOOL CFighterDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default
	if (m_bShowHandCursor)
	{
		SetCursor(AfxGetApp()->LoadCursor(IDC_HAND));
		return TRUE;
	};

	if(m_bShowShootingCursor)
	{
		SetCursor(m_hNewCursor);
		return TRUE;
	}
	return CDialog::OnSetCursor(pWnd, nHitTest, message);
}

void CFighterDlg::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	static int nCurrentState = STATE_COLD;
	static int nLastState = STATE_COLD;

	if(m_rectSky.PtInRect(point))
	{
		nCurrentState = STATE_COLD;
		m_bShowShootingCursor = TRUE;
		return;
	}
	else
		m_bShowShootingCursor = FALSE;

	if(m_rectNew.PtInRect(point))
	{
		nCurrentState = STATE_HOT;
		if (nLastState!=nCurrentState)
		{
			if(m_bSound)PlaySound("Start.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);
//			m_ctrlNew.UnLoad();
//			m_ctrlNew.Load(MAKEINTRESOURCE(IDR_GIF_HOTNEW),_T("Gif"));
			nLastState = nCurrentState;
//			m_ctrlNew.SetBkColor(RGB(255, 255, 255));
//			m_ctrlNew.Draw();	
		}
		m_bShowHandCursor = TRUE;
		return;
	}
/*	if(m_rectNew.PtInRect(point))
	{
		nCurrentState = STATE_HOT;
		if (nLastState!=nCurrentState)
		{
			nLastState = nCurrentState;
			m_ctrlNew.DrawHotBitmap();	
		}
		m_bShowHandCursor = TRUE;
		return;
	}
*/	
/*	if(m_rectPosition.PtInRect(point))
	{
		nCurrentState = STATE_HOT;
		if (nLastState!=nCurrentState && m_ctrlPosition.Load(MAKEINTRESOURCE(IDR_GIF_HOTPOSITION),_T("Gif")))
		{
			nLastState = nCurrentState;
			m_ctrlPosition.SetBkColor(RGB(255, 255, 255));
			m_ctrlPosition.Draw();	
		}
		m_bShowHandCursor = TRUE;
		return;
	}*/
	if(m_rectPosition.PtInRect(point))
	{
		nCurrentState = STATE_HOT;
		if (nLastState!=nCurrentState)
		{
			if(m_bSound)PlaySound("Start.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);
//			m_ctrlPosition.UnLoad();
//			m_ctrlPosition.Load(MAKEINTRESOURCE(IDR_GIF_HOTPOSITION),_T("Gif"));
			nLastState = nCurrentState;
			//m_ctrlPosition.PlayPlay();
//			m_ctrlPosition.Draw();	
		}
		m_bShowHandCursor = TRUE;
		return;
	}
	
	if(m_rectSave.PtInRect(point))
	{
		nCurrentState = STATE_HOT;
		if (nLastState!=nCurrentState)
		{
			if(m_bSound)PlaySound("Start.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);
//			m_ctrlSave.UnLoad();
//			m_ctrlSave.Load(MAKEINTRESOURCE(IDR_GIF_HOTSAVE),_T("Gif"));
			nLastState = nCurrentState;
//			m_ctrlSave.SetBkColor(RGB(255, 255, 255));
//			m_ctrlSave.Draw();	
		}
		m_bShowHandCursor = TRUE;
		return;
	}

	if(m_rectOption.PtInRect(point))
	{
		nCurrentState = STATE_HOT;
		if (nLastState!=nCurrentState)
		{
			if(m_bSound)PlaySound("Start.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);
//			m_ctrlOption.UnLoad();
//			m_ctrlOption.Load(MAKEINTRESOURCE(IDR_GIF_HOTOPTION),_T("Gif"));
			nLastState = nCurrentState;
//			m_ctrlOption.SetBkColor(RGB(255, 255, 255));
//			m_ctrlOption.Draw();	
		}
		m_bShowHandCursor = TRUE;
		return;
	}

	if(m_rectLoad.PtInRect(point))
	{
		nCurrentState = STATE_HOT;
		if (nLastState!=nCurrentState)
		{
			if(m_bSound)PlaySound("Start.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);
//			m_ctrlLoad.UnLoad();
//			m_ctrlLoad.Load(MAKEINTRESOURCE(IDR_GIF_HOTLOAD),_T("Gif"));
			nLastState = nCurrentState;
//			m_ctrlLoad.SetBkColor(RGB(255, 255, 255));
//			m_ctrlLoad.Draw();	
		}
		m_bShowHandCursor = TRUE;
		return;
	}

	if(m_rectQuit.PtInRect(point))
	{
		nCurrentState = STATE_HOT;
		if (nLastState!=nCurrentState)
		{
			if(m_bSound)PlaySound("Start.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);
//			m_ctrlQuit.UnLoad();
//			m_ctrlQuit.Load(MAKEINTRESOURCE(IDR_GIF_HOTQUIT),_T("Gif"));
			nLastState = nCurrentState;
//			m_ctrlQuit.SetBkColor(RGB(255, 255, 255));
//			m_ctrlQuit.Draw();	
		}
		m_bShowHandCursor = TRUE;
		return;
	}

	m_bShowHandCursor = FALSE;

	nCurrentState = STATE_COLD;

	if(nLastState!=nCurrentState)
	{
		nLastState = nCurrentState;
/*		m_ctrlNew.UnLoad();
		if (m_ctrlNew.Load(MAKEINTRESOURCE(IDR_GIF_NEW),_T("Gif")))
		{
			m_ctrlNew.SetBkColor(RGB(255, 255, 255));
			m_ctrlNew.Draw();	
		}
		m_ctrlNew.DrawCoolBitmap();

		m_ctrlPosition.UnLoad();
		if (m_ctrlPosition.Load(MAKEINTRESOURCE(IDR_GIF_POSITION),_T("Gif")))
		{
			m_ctrlPosition.SetBkColor(RGB(255, 255, 255));
			m_ctrlPosition.Draw();	
		}
		m_ctrlSave.UnLoad();
		if (m_ctrlSave.Load(MAKEINTRESOURCE(IDR_GIF_SAVE),_T("Gif")))
		{
			m_ctrlSave.SetBkColor(RGB(255, 255, 255));
			m_ctrlSave.Draw();	
		}
		m_ctrlOption.UnLoad();
		if (m_ctrlOption.Load(MAKEINTRESOURCE(IDR_GIF_OPTION),_T("Gif")))
		{
			m_ctrlOption.SetBkColor(RGB(255, 255, 255));
			m_ctrlOption.Draw();	
		}
		m_ctrlLoad.UnLoad();
		if (m_ctrlLoad.Load(MAKEINTRESOURCE(IDR_GIF_LOAD),_T("Gif")))
		{
			m_ctrlLoad.SetBkColor(RGB(255, 255, 255));
			m_ctrlLoad.Draw();	
		}
		m_ctrlQuit.UnLoad();
		if (m_ctrlQuit.Load(MAKEINTRESOURCE(IDR_GIF_QUIT),_T("Gif")))
		{
			m_ctrlQuit.SetBkColor(RGB(255, 255, 255));
			m_ctrlQuit.Draw();	
		}
*/	}

//	CDialog::OnMouseMove(nFlags, point);
}
/*
void CFighterDlg::OnClickNew()
{
	if(m_nGameStatus==FIGHTER_POSITION)
	{
		CFighterInfo fighter;
		for(int i=0; i<10; i++)
		{
			for(int j=0; j<10; j++)
			{
				if(m_nShootingResult[i][j] == FIGHTER_POSITION_NULL)
					fighter.m_nSky[i][j] = FIGHTER_NULL;
				else if(m_nShootingResult[i][j] == FIGHTER_POSITION_BODY)
					fighter.m_nSky[i][j] = FIGHTER_BODY;
				else
					fighter.m_nSky[i][j] = FIGHTER_HEAD;
				TRACE("%d, ", m_nShootingResult[i][j]);
			}
			TRACE("\n");
		}
		if(!fighter.IsSkyValid())
		{
			AfxMessageBox("???ֲ???ȷ???????²??֡?");
			return;
		}
		for(int k=0; k<10; k++)
			for(int l=0; l<10; l++)
			{
				m_nSky[k][l] = fighter.m_nSky[k][l];
				m_nShootingResult[k][l] = 0;
			}
	}
	else
	{
		if(m_nGameStatus == FIGHTER_RUNNING)
		{
			if(MessageBox("??Ϸ?????С???Ҫ???¿?ʼ??", "??ɻ?????????",MB_YESNO)!=IDYES)
				return;
		}
		for(int i=0; i<10; i++)
			for(int j=0; j<10; j++)
			{
				m_nShootingResult[i][j] = 0;
				m_nSky[i][j] = 0;
			}

		for(i=0; i<3; i++){
			CFighterInfo fighter;
			for(int k=0; k<10; k++)
				for(int l=0; l<10; l++)
					fighter.m_nSky[k][l] = m_nSky[k][l];
			do{
				fighter.SetHeadPos(CPoint(GetRand_10(), GetRand_10()));
				fighter.SetFighterPosition(GetRand_4());
			}while(!fighter.IsFighterValid());
			fighter.SetItInSky();
			for(k=0; k<10; k++)
				for(int l=0; l<10; l++)
					m_nSky[k][l] = fighter.m_nSky[k][l];
		}
	}

	m_nFighterDown = 0;
	m_nFighterHit = 0;
	m_nBomb = 0;

	if(m_nWelcomeTimer)
	{
		KillTimer(m_nWelcomeTimer);
		m_nWelcomeTimer = 0;
	}	

	m_strComment1 = "";
	m_strComment2 = "";
	m_strComment3 = "";
	m_strComment4 = "??ע??";
	m_strComment5 = "??Ϸ??ʼ";

	m_ptComment.y = m_rectCommentFrame.top;

	m_nGameStatus = FIGHTER_RUNNING;

	if(!m_nCommentTimer)
	{
		KillTimer(m_nCommentTimer);
		m_nCommentTimer = SetTimer(FIGHTER_COMMENT_TIMER, FIGHTER_SCRROLTIME, NULL);
	}
	InvalidateRect(m_rectSky, TRUE);
}

void CFighterDlg::OnClickPosition()
{
	if(m_nGameStatus == FIGHTER_RUNNING)
	{
		if(MessageBox("??Ϸ?????С???Ҫ?????ֶ???????", "??ɻ?????????", MB_OKCANCEL)==IDCANCEL)
			return;
	}

	m_nGameStatus = FIGHTER_POSITION;
	m_bByComputer = FALSE;

	for(int i=0; i<10; i++)
		for(int j=0; j<10; j++)
			m_nShootingResult[i][j] = FIGHTER_POSITION_NULL;

	m_strComment1 = "";
	m_strComment2 = "";
	m_strComment3 = "";
	m_strComment4 = "?ֶ????ֿ?ʼ";
	m_strComment5 = "???ס???ֹ???";

	if(m_nWelcomeTimer)
	{
		KillTimer(m_nWelcomeTimer);
		m_nWelcomeTimer = 0;
	}	

	if(!m_nCommentTimer)
		KillTimer(m_nCommentTimer);
	m_nCommentTimer = SetTimer(FIGHTER_COMMENT_TIMER, FIGHTER_SCRROLTIME, NULL);

	InvalidateRect(m_rectSky, FALSE);
}
void CFighterDlg::OnClickSave()
{
	if(m_nGameStatus==FIGHTER_POSITION)
	{
		CFighterInfo fighter;
		for(int i=0; i<10; i++)
			for(int j=0; j<10; j++)
			{
				if(m_nShootingResult[i][j] == FIGHTER_POSITION_NULL)
					fighter.m_nSky[i][j] = FIGHTER_NULL;
				else if(m_nShootingResult[i][j] == FIGHTER_POSITION_BODY)
					fighter.m_nSky[i][j] = FIGHTER_BODY;
				else
					fighter.m_nSky[i][j] = FIGHTER_HEAD;
			}
		if(!fighter.IsSkyValid())
		{
			AfxMessageBox("???ֲ???ȷ???????²??֡?");
			return;
		}
		for(int k=0; k<10; k++)
			for(int l=0; l<10; l++)
				m_nSky[k][l] = fighter.m_nSky[k][l];
	}

	BOOL bSkyNULL = TRUE;
	for(int i=0; i<10; i++)
		for(int j=0; j<10; j++)
			if(m_nSky[i][j]!=0)bSkyNULL=FALSE;
	if(bSkyNULL)
	{
		AfxMessageBox("??Ϸ??δ??ʼ?????ȵ????????Ϸ??");
		return;
	}

	CFileDialog dlgFile(
		FALSE, _T("*.pos"), NULL,
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		_T("?????ļ?(*.pos)|*.pos||"));

	if (dlgFile.DoModal() == IDCANCEL)
		return ;

	CString sPath = dlgFile.GetPathName();

	CFile file;
	if(file.Open((LPCTSTR)sPath, CFile::modeCreate|CFile::modeWrite)==FALSE)
	{
		AfxMessageBox("??pos?ļ?ʧ?ܣ?");
		return;
	}

	SAVEPOSITION data;
	data.dwVersion = 0x00000100;

	for(i=0; i<10; i++)
		for(int j=0; j<10; j++)
			data.nSky[i][j] = m_nSky[i][j];

	file.Write(&data, sizeof(SAVEPOSITION));

	file.Close();

	m_ptComment.y = m_rectCommentFrame.top;
	m_strComment1 = m_strComment3;
	m_strComment2 = m_strComment4;
	m_strComment3 = m_strComment5;
	m_strComment4 = "?????ļ???...";
	m_strComment5 = "????ɹ???";
	if(!m_nCommentTimer)
	{
		KillTimer(m_nCommentTimer);
		m_nCommentTimer = SetTimer(FIGHTER_COMMENT_TIMER, FIGHTER_SCRROLTIME, NULL);
	}
}
void CFighterDlg::OnClickOption()
{
	CPropertySheet Sheet("ѡ??", this, 0);

	CRankPage rankPage;
	for(int i=0; i<10; i++)
	{
		rankPage.m_fHitPercentage[i] = m_TopTen.hitpercentage[i];
		rankPage.m_nBomb[i] = m_TopTen.bomb[i];
		sprintf(rankPage.m_strName[i], "%s", m_TopTen.name[i]);
	}

	COperationPage operationPage;
	CAboutPage aboutPage;
	CSettingPage settingPage;
	settingPage.m_strBossFile = m_strBossFile;

	Sheet.m_psh.dwFlags &= ~PSH_HASHELP;
	Sheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;

	Sheet.AddPage(&settingPage);
	Sheet.AddPage(&rankPage);
	Sheet.AddPage(&operationPage);
	Sheet.AddPage(&aboutPage);

	if(Sheet.DoModal()==IDOK)
	{
		m_strBossFile = settingPage.m_strBossFile;

		if(settingPage.m_bShortcut)
		{
			CString strShortcutText;
			strShortcutText = settingPage.m_strShortcutName;

			char pathname[_MAX_PATH];
			GetModuleFileName(NULL, pathname, _MAX_PATH);//??ִ???ļ?????Ŀ¼

			char winpath[_MAX_PATH];
			::GetWindowsDirectory(winpath, _MAX_PATH);
			CString destPath = winpath;
			destPath += "\\Desktop\\";
			destPath += (strShortcutText.Right(4)==".lnk")?(strShortcutText):(strShortcutText+".lnk");

			FileLink(pathname, (LPCTSTR)destPath);
		}
	}
}
void CFighterDlg::OnClickLoad()
{
	if(m_nGameStatus == FIGHTER_RUNNING)
	{
		if(MessageBox("??Ϸ?????С???Ҫ??????һ??Ϸ??", "??ɻ?????????", MB_OKCANCEL)==IDCANCEL)
			return;
	}

	CFileDialog dlgFile(
		TRUE, _T("*.pos"), NULL,
		OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
		_T("?????ļ?(*.pos)|*.pos||"));

	if (dlgFile.DoModal() == IDCANCEL)
		return ;

	CString sPath = dlgFile.GetPathName();
	CString sExt = dlgFile.GetFileExt();
	sExt.MakeLower();
	if(sExt != "pos")
	{
		AfxMessageBox("??ѡ??pos?ļ???");
		return;
	}

	CFile file;
	if(file.Open((LPCTSTR)sPath, CFile::modeRead)==FALSE)
	{
		AfxMessageBox("??pos?ļ?ʧ?ܣ?");
		return;
	}

	SAVEPOSITION data;
	if(file.Read(&data, sizeof(SAVEPOSITION))==0)
	{
		AfxMessageBox("????pos?ļ?ʧ?ܣ?");
		return;
	}

	file.Close();

	for(int i=0; i<10; i++)
		for(int j=0; j<10; j++)
		{
			if(data.nSky[i][j]<0 || data.nSky[i][j]>2)
			{
				AfxMessageBox("Error: the load file may be corrupted");
				return;
			}
			m_nSky[i][j] = data.nSky[i][j];
		}


	m_ptComment.y = m_rectCommentFrame.top;
	m_strComment1 = m_strComment3;
	m_strComment2 = m_strComment4;
	m_strComment3 = m_strComment5;
	m_strComment4 = "?????ļ???...";
	m_strComment5 = "????ɹ???";
	if(!m_nCommentTimer)
	{
		KillTimer(m_nCommentTimer);
		m_nCommentTimer = SetTimer(FIGHTER_COMMENT_TIMER, FIGHTER_SCRROLTIME, NULL);
	}

	for(i=0; i<10; i++)
		for(int j=0; j<10; j++)
			m_nShootingResult[i][j] = 0;

	m_nFighterDown = 0;
	m_nFighterHit = 0;
	m_nBomb = 0;

	if(m_nWelcomeTimer)
	{
		KillTimer(m_nWelcomeTimer);
		m_nWelcomeTimer = 0;
	}	

	m_nGameStatus = FIGHTER_RUNNING;

	InvalidateRect(m_rectSky, FALSE);
	InvalidateRect(m_rectCommentFrame, FALSE);
}
void CFighterDlg::OnClickQuit()
{
	CQuitDlg dlg;
	if(dlg.DoModal()==IDCANCEL)
		return;
	SendMessage(WM_CLOSE);
}
*/
int CFighterDlg::GetRand_10()
{
	int nRand = rand();
	return nRand%10;
}

int CFighterDlg::GetRand_4()
{
	int nRand = rand();
	return nRand%4;
}
/***********************************************************
*  DrawShootingResult??ʾm_nShootingResult????? 
*	pDC??Ϊ?ڴ?ָ??
*
*
************************************************************/
void CFighterDlg::DrawShootingResult(CDC *pDC)
{
	for(int i=0; i<10; i++)
		for(int j=0; j<10; j++){
			if(m_nShootingResult[i][j] != 0)
				DrawPiece(pDC, m_rectSky.left+i*PIECE_SIDE+1,
				m_rectSky.top+j*PIECE_SIDE+1, m_nShootingResult[i][j]);
//			if(m_nSky[i][j] != 0)
//				DrawPiece(pDC, m_rectSky.left+i*PIECE_SIDE+1,
//				m_rectSky.top+j*PIECE_SIDE+1, m_nSky[i][j]);
		}
}

void CFighterDlg::DrawPiece(CDC *pDC, int x, int y, int nResult)
{
	switch(nResult)
	{
	case FIGHTER_GUESS_HITNULL:
		{
		CBrush brush(RGB(0, 0, 255));
		pDC->FillRect(CRect(x, y, x+PIECE_SIDE-2, y+PIECE_SIDE-2), &brush);
		break;
		}
	case FIGHTER_GUESS_HIT:
		{
		CBrush brush(RGB(200, 200, 200));
		pDC->FillRect(CRect(x, y, x+PIECE_SIDE-2, y+PIECE_SIDE-2), &brush);
		break;
		}
	case FIGHTER_HITNULL:
	case FIGHTER_POSITION_NULL:
		{
		CBrush brush(RGB(0, 0, 0));
		pDC->FillRect(CRect(x, y, x+PIECE_SIDE-2, y+PIECE_SIDE-2), &brush);
		break;
		}
	case FIGHTER_HIT:
	case FIGHTER_POSITION_BODY:
		{
		CBrush brush(RGB(100, 100, 100));
		pDC->FillRect(CRect(x, y, x+PIECE_SIDE-2, y+PIECE_SIDE-2), &brush);
		break;
		}
	case FIGHTER_HITDOWN:
	case FIGHTER_POSITION_HEADER:
		{
		CBrush brush(RGB(255, 0, 0));
		pDC->FillRect(CRect(x, y, x+PIECE_SIDE-2, y+PIECE_SIDE-2), &brush);
		break;
		}
	default:
		break;
	}
}

void CFighterDlg::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(!m_rectSky.PtInRect(point))
		return;
	if(m_nGameStatus==FIGHTER_STOP)
		OnButtonNew();

	CPoint ptShootingAt;
	ptShootingAt = CPoint((point.x-m_rectSky.left)/PIECE_SIDE,
		(point.y-m_rectSky.top)/PIECE_SIDE);
	m_nBomb ++;
	InvalidateRect(m_rectBomb, TRUE);

	switch(m_nShootingResult[ptShootingAt.x][ptShootingAt.y])
	{
	case FIGHTER_UNEXPLORE:
	case FIGHTER_GUESS_HITNULL:
	case FIGHTER_GUESS_HIT:
		if(m_nSky[ptShootingAt.x][ptShootingAt.y] == FIGHTER_HEAD){
			if(m_bSound)PlaySound("fall.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);
			m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_HITDOWN;
			m_nFighterDown ++;
			m_nFighterHit ++;
//			m_bCommentOut = TRUE;
			if(m_ptComment.y<m_rectCommentFrame.top-48)
			{
				m_ptComment.y = m_rectCommentFrame.top;
			}
			m_strComment1 = m_strComment3;
			m_strComment2 = m_strComment4;
			m_strComment3 = m_strComment5;
			m_strComment4.LoadString(IDS_GOOD);
			m_strComment5.LoadString(IDS_FALLDOWN);
			InvalidateRect(m_rectFighterHit, TRUE);
			InvalidateRect(m_rectFighterDown, TRUE);
		}
		else if(m_nSky[ptShootingAt.x][ptShootingAt.y] == FIGHTER_BODY)
		{
			if(m_bSound)PlaySound("hit.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);
			m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_HIT;
			m_nFighterHit ++;
//			m_bCommentOut = TRUE;
			if(m_ptComment.y<m_rectCommentFrame.top-48)
			{
				m_ptComment.y = m_rectCommentFrame.top;
			}
			m_strComment1 = m_strComment3;
			m_strComment2 = m_strComment4;
			m_strComment3 = m_strComment5;
			m_strComment4.LoadString(IDS_HIT);
			m_strComment5.LoadString(IDS_OK);
			InvalidateRect(m_rectFighterHit, TRUE);
		}
		else if(m_nSky[ptShootingAt.x][ptShootingAt.y] == FIGHTER_NULL)
		{
			if(m_bSound)PlaySound("shooting.wav", NULL, SND_FILENAME|SND_ASYNC|SND_NODEFAULT);
			m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_HITNULL;
//			m_bCommentOut = TRUE;
			if(m_ptComment.y<m_rectCommentFrame.top-48)
			{
				m_ptComment.y = m_rectCommentFrame.top;
			}
			m_strComment1 = m_strComment3;
			m_strComment2 = m_strComment4;
			m_strComment3 = m_strComment5;
			m_strComment4.LoadString(IDS_SORRY);
			m_strComment5.LoadString(IDS_FAILURE);
		}

		InvalidateRect(
			CRect(m_rectSky.left+ptShootingAt.x*PIECE_SIDE+1,
			m_rectSky.top+ptShootingAt.y*PIECE_SIDE+1,
			m_rectSky.left+(ptShootingAt.x+1)*PIECE_SIDE-1,
			m_rectSky.top +(ptShootingAt.y+1)*PIECE_SIDE-1), TRUE);
		if(!m_nCommentTimer)
			m_nCommentTimer = SetTimer(FIGHTER_COMMENT_TIMER, FIGHTER_SCRROLTIME, NULL);
		break;
	case FIGHTER_HITDOWN:
	case FIGHTER_HIT:
	case FIGHTER_HITNULL:
		break;
	default:
		break;
	}

	if(m_nFighterDown == 3)
	{
		m_nGameStatus = FIGHTER_STOP;
		if(IsEnterTopTen(m_nBomb))
		{
			EnterTopTen();
			for(int i=0; i<10; i++)
				for(int j=0; j<10; j++){
					m_nShootingResult[i][j] = m_nSky[i][j];
				}
		}

		Invalidate(FALSE);
	}

//	CDialog::OnLButtonDblClk(nFlags, point);
}

void CFighterDlg::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(!m_rectSky.PtInRect(point)||	m_nGameStatus==FIGHTER_STOP)
		return;

	CPoint ptShootingAt;
	ptShootingAt = CPoint((point.x-m_rectSky.left)/PIECE_SIDE,
		(point.y-m_rectSky.top)/PIECE_SIDE);

	switch(m_nShootingResult[ptShootingAt.x][ptShootingAt.y])
	{
	case FIGHTER_UNEXPLORE:
	case FIGHTER_GUESS_HIT:
		m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_GUESS_HITNULL;
		InvalidateRect(
			CRect(m_rectSky.left+ptShootingAt.x*PIECE_SIDE+1,
			m_rectSky.top+ptShootingAt.y*PIECE_SIDE+1,
			m_rectSky.left+(ptShootingAt.x+1)*PIECE_SIDE-1,
			m_rectSky.top +(ptShootingAt.y+1)*PIECE_SIDE-1), FALSE);
		break;
	case FIGHTER_GUESS_HITNULL:
		m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_UNEXPLORE;
//		InvalidateRect(NULL);
		InvalidateRect(
			CRect(m_rectSky.left+ptShootingAt.x*PIECE_SIDE+1,
			m_rectSky.top+ptShootingAt.y*PIECE_SIDE+1,
			m_rectSky.left+(ptShootingAt.x+1)*PIECE_SIDE-1,
			m_rectSky.top +(ptShootingAt.y+1)*PIECE_SIDE-1), FALSE);
		break;
	case FIGHTER_HITDOWN:
	case FIGHTER_HIT:
	case FIGHTER_HITNULL:
		break;
	case FIGHTER_POSITION_NULL:
	case FIGHTER_POSITION_HEADER:
		m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_POSITION_BODY;
		InvalidateRect(
			CRect(m_rectSky.left+ptShootingAt.x*PIECE_SIDE+1,
			m_rectSky.top+ptShootingAt.y*PIECE_SIDE+1,
			m_rectSky.left+(ptShootingAt.x+1)*PIECE_SIDE-1,
			m_rectSky.top +(ptShootingAt.y+1)*PIECE_SIDE-1), FALSE);
		break;
	case FIGHTER_POSITION_BODY:
		m_nShootingResult[ptShootingAt.x][ptShootingAt.y] = FIGHTER_POSITION_NULL;
		InvalidateRect(
			CRect(m_rectSky.left+ptShootingAt.x*PIECE_SIDE+1,
			m_rectSky.top+ptShootingAt.y*PIECE_SIDE+1,
			m_rectSky.left+(ptShootingAt.x+1)*PIECE_SIDE-1,
			m_rectSky.top +(ptShootingAt.y+1)*PIECE_SIDE-1), FALSE);
		break;
	default:
		break;
	}
}

void CFighterDlg::DrawComment(CDC *pDC)
{
	CRgn rgn;
	rgn.CreateRectRgnIndirect(m_rectCommentFrame);
	pDC->SelectClipRgn(&rgn, RGN_COPY);
	COLORREF oldColor = pDC->SetTextColor(RGB(255,255,255));
	int nOldMode = pDC->SetBkMode(TRANSPARENT);
	pDC->TextOut(m_ptComment.x+5, m_ptComment.y+4, m_strComment1);
	pDC->TextOut(m_ptComment.x+5, m_ptComment.y+28, m_strComment2);
	pDC->TextOut(m_ptComment.x+5, m_ptComment.y+52, m_strComment3);
	pDC->TextOut(m_ptComment.x+5, m_ptComment.y+76, m_strComment4);
	pDC->TextOut(m_ptComment.x+5, m_ptComment.y+100, m_strComment5);
	pDC->SetTextColor(oldColor);
	pDC->SetBkMode(nOldMode);
	pDC->SelectClipRgn(NULL, RGN_COPY);
}

void CFighterDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	switch(nIDEvent)
	{
	case FIGHTER_COMMENT_TIMER:
		m_ptComment.y-=2;
		if(m_ptComment.y<m_rectCommentFrame.top-48){
//			m_rectComment.top = m_rectCommentFrame.top;
			KillTimer(m_nCommentTimer);
			m_nCommentTimer = 0;
//			m_strComment1 = m_strComment3;
//			m_strComment2 = m_strComment4;
//			m_strComment3 = m_strComment5;
			InvalidateRect(m_rectCommentFrame, FALSE);
			return;
		}
		InvalidateRect(m_rectCommentFrame, FALSE);
		break;
	case FIGHTER_WELCOME_TIMER:
		m_ptComment.y-=2;
		if(m_bLoadWelcomeString)
		{
			m_strComment1.LoadString(IDS_WELCOME1);
			m_strComment2.LoadString(IDS_WELCOME2);
			m_strComment3.LoadString(IDS_WELCOME3);
			m_strComment4.LoadString(IDS_WELCOME4);
			m_strComment5.LoadString(IDS_WELCOME5);
			m_bLoadWelcomeString = FALSE;
		}
		if(m_ptComment.y<m_rectCommentFrame.top-48)
		{
			m_ptComment.y = m_rectCommentFrame.top;
			m_strComment1 = m_strComment3;
			m_strComment2 = m_strComment4;
			m_strComment3 = m_strComment5;
			m_strComment4 = m_strComment1;
			m_strComment5 = m_strComment2;
		}
		InvalidateRect(m_rectCommentFrame, FALSE);
		break;
	default:
		break;
	}
//	CDialog::OnTimer(nIDEvent);
}

BOOL CFighterDlg::ReadRankFile(TOPTEN *pTopTen)
{
	CFile file;
	if(!file.Open("fighter.rnk", CFile::modeRead))
		return FALSE;
	int nRead, nSizeOf;
	nSizeOf = sizeof(TOPTEN);
	nRead = file.Read(pTopTen, sizeof(TOPTEN));
	if(!nRead)
		return FALSE;

	return TRUE;
}

BOOL CFighterDlg::WriteRankFile(TOPTEN TopTen)
{
	CFile file;

	if(!file.Open("fighter.rnk", CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
		return FALSE;
	try
	{
		file.Write(&TopTen, sizeof(TOPTEN));
	}
	catch(CFileException e)
	{
#ifdef _DEBUG
		afxDump << "File could not be opened " << e.m_cause << "\n";
#endif
		return FALSE;
	}

	return TRUE;
}

BOOL CFighterDlg::IsEnterTopTen(int nBomb)
{
	if(nBomb<m_TopTen.bomb[9] || m_TopTen.bomb[9]==0)
		return TRUE;

	return FALSE;
}

void CFighterDlg::EnterTopTen()
{
	CCongraduationDlg dlg;
	dlg.m_bSound = m_bSound;
	dlg.m_nBomb = m_nBomb;
	dlg.m_strPercentage.Format("%2.1f%%", m_nFighterHit*100.0/m_nBomb);
	dlg.DoModal();

	if(dlg.m_strName.IsEmpty())
		return;

	for(int i=8; i>=0; i--)
	{
		if(m_nBomb<m_TopTen.bomb[i]||m_TopTen.bomb[i]==0)
		{
			sprintf(m_TopTen.name[i+1], "%s", m_TopTen.name[i]);
			m_TopTen.bomb[i+1] = m_TopTen.bomb[i];
			m_TopTen.hitpercentage[i+1] = m_TopTen.hitpercentage[i];
		}
		else if(m_nBomb==m_TopTen.bomb[i] && ((float)m_nFighterHit/m_nBomb>m_TopTen.hitpercentage[i]))
		{
			sprintf(m_TopTen.name[i+1], "%s", m_TopTen.name[i]);
			m_TopTen.bomb[i+1] = m_TopTen.bomb[i];
			m_TopTen.hitpercentage[i+1] = m_TopTen.hitpercentage[i];
		}
		else
			break;
	}

	sprintf(m_TopTen.name[i+1], "%s", (LPCTSTR)dlg.m_strName);
	m_TopTen.bomb[i+1] = m_nBomb;
	m_TopTen.hitpercentage[i+1] = m_nFighterHit*100.0/m_nBomb;

	CPropertySheet Sheet("ѡ??", this, 1);

	CRankPage rankPage;
	for(i=0; i<10; i++)
	{
		rankPage.m_fHitPercentage[i] = m_TopTen.hitpercentage[i];
		rankPage.m_nBomb[i] = m_TopTen.bomb[i];
		sprintf(rankPage.m_strName[i], "%s", m_TopTen.name[i]);
	}

	COperationPage operationPage;
	CAboutPage aboutPage;
	CSettingPage settingPage;
	settingPage.m_strBossFile = m_strBossFile;

	Sheet.m_psh.dwFlags &= ~PSH_HASHELP;
	Sheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;

	Sheet.AddPage(&settingPage);
	Sheet.AddPage(&rankPage);
	Sheet.AddPage(&operationPage);
	Sheet.AddPage(&aboutPage);

	if(Sheet.DoModal()==IDOK)
	{
		m_strBossFile = settingPage.m_strBossFile;
		m_bSound = settingPage.m_bSound;

		if(settingPage.m_bShortcut)
		{
			CString strShortcutText;
			strShortcutText = settingPage.m_strShortcutName;

			char pathname[_MAX_PATH];
			GetModuleFileName(NULL, pathname, _MAX_PATH);//??ִ???ļ?????Ŀ¼

			char winpath[_MAX_PATH];
			::GetWindowsDirectory(winpath, _MAX_PATH);
			CString destPath = winpath;
			destPath += "\\Desktop\\";
			destPath += (strShortcutText.Right(4)==".lnk")?(strShortcutText):(strShortcutText+".lnk");

			FileLink(pathname, (LPCTSTR)destPath);
		}
	}
/*	CRankDlg rankDlg;
	for(i=0; i<10; i++)
	{
		sprintf(rankDlg.m_strName[i], "%s", m_TopTen.name[i]);
		rankDlg.m_nBomb[i] = m_TopTen.bomb[i];
		rankDlg.m_fHitPercentage[i] = m_TopTen.hitpercentage[i];
	}

	rankDlg.DoModal();
*/
	WriteRankFile(m_TopTen);
}

/*void CFighterDlg::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	// TODO: Add your message handler code here
//	LPPOINT lpoint = new POINT;
//	::GetCursorPos(lpoint);//?õ????λ??

	CRect rect;
	m_ctrlPosition.GetWindowRect(&rect);
	if(!rect.PtInRect(point))
		return;

	CNewMenu m_menu;
	CNewMenu *pMenu;

	m_menu.LoadMenu(IDR_MENU_POPUP);
//	m_menu.LoadToolbar(IDR_TOOLBAR);

	pMenu = (CNewMenu*)m_menu.GetSubMenu(0);
//	pMenu->SetMenuDrawMode(BCMENU_DRAWMODE_XP);
	m_bSoundOn?(pMenu->CheckMenuItem(ID_MENU_SOUND, MF_CHECKED|MF_BYCOMMAND)):
		pMenu->CheckMenuItem(ID_MENU_SOUND, MF_UNCHECKED|MF_BYCOMMAND);
	m_bByComputer?(pMenu->CheckMenuItem(ID_MENU_BYCOMPUTER, MF_CHECKED|MF_BYCOMMAND)):
		pMenu->CheckMenuItem(ID_MENU_BYCOMPUTER, MF_UNCHECKED|MF_BYCOMMAND);
	m_bByComputer?(pMenu->CheckMenuItem(ID_MENU_BYHAND, MF_UNCHECKED|MF_BYCOMMAND)):
		pMenu->CheckMenuItem(ID_MENU_BYHAND, MF_CHECKED|MF_BYCOMMAND);
	pMenu->TrackPopupMenu (TPM_LEFTALIGN, rect.right, rect.top, this);

	m_menu.DestroyMenu();	

//	delete lpoint;
}*/


BOOL CFighterDlg::FileLink(LPCTSTR strPathObj, LPCTSTR strPathLink)
{
	BOOL bRet = FALSE;
	IShellLink* psl;

	if (SUCCEEDED( CoCreateInstance(CLSID_ShellLink,
							NULL,
							CLSCTX_INPROC_SERVER,
							IID_IShellLink,
							(LPVOID*) &psl)))
	{
		IPersistFile* ppf;

		psl->SetPath(strPathObj);

		if (SUCCEEDED(psl->QueryInterface( IID_IPersistFile, (LPVOID *) &ppf)))
		{

			WORD wsz[MAX_PATH];
			MultiByteToWideChar(CP_ACP, 
								MB_PRECOMPOSED, 
								strPathLink, 
								-1, 
								wsz,
								MAX_PATH);

			if ( SUCCEEDED ( ppf->Save(wsz, TRUE) ) )
				bRet = TRUE;

			ppf->Release();
		}
		psl->Release();
	}

	return bRet;
}

void CFighterDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	switch(nChar){
	case 'Q'://?ϰ??
	case 'W':
	case 192:
//	case 'q':
		ShowWindow(SW_HIDE);
		m_bShow = FALSE;

		//???ַ??????ϰ???ļ???????
//		char buf[512];
//		sprintf(buf, "notepad \"%s\"", m_strBossFile);
//		WinExec(buf, SW_MAXIMIZE);

		ShellExecute(NULL, _T("open"), (LPCTSTR)m_strBossFile, NULL, NULL, SW_MAXIMIZE);

		break;
	case VK_F2://????????Ϸ
		OnButtonNew();
		break;
	case VK_RETURN:
	case VK_ESCAPE:
		OnButtonQuit();
		break;
	default:
		break;
	}
		
	CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CFighterDlg::OnClickTrayIcon(WPARAM wParam, LPARAM lParam)
{
	if(wParam!=IDR_MAINFRAME)
		return;
    switch(lParam)
    {
	case WM_RBUTTONUP:
		{
			BCMenu m_menu;
			BCMenu *pMenu;

			LPPOINT lpoint = new POINT;
			::GetCursorPos(lpoint);

			m_menu.LoadMenu(IDR_MENU_POPUP);
		//	m_menu.LoadToolbar(IDR_MAINFRAME);
			m_menu.LoadToolbar(IDR_TOOLBAR);

			pMenu = (BCMenu*)m_menu.GetSubMenu(0);
			pMenu->SetMenuDrawMode(BCMENU_DRAWMODE_XP);
			m_bShow?pMenu->CheckMenuItem(ID_MENU_SHOW, MF_CHECKED|MF_BYCOMMAND):
				pMenu->CheckMenuItem(ID_MENU_SHOW, MF_UNCHECKED|MF_BYCOMMAND);
			m_bSound?pMenu->CheckMenuItem(ID_MENU_SOUND, MF_CHECKED|MF_BYCOMMAND):
				pMenu->CheckMenuItem(ID_MENU_SOUND, MF_UNCHECKED|MF_BYCOMMAND);

			pMenu->TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);

			m_menu.DestroyMenu();	

			delete lpoint;
		}
		break;
    case WM_LBUTTONDBLCLK:
		{
			this->ShowWindow(SW_SHOW);
			m_bShow = TRUE;
		}
		break;
    }
    return;	
}

BOOL CFighterDlg::PreTranslateMessage(MSG* pMsg) 
{
	// TODO: Add your specialized code here and/or call the base class
	if(pMsg->message==WM_KEYDOWN)
	{
		//???????
		OnKeyDown((UINT)pMsg->wParam, (UINT)0, (UINT)0);
	}
	
	return CDialog::PreTranslateMessage(pMsg);
}
/********************************************************
*????˵????ʾ
*??????ʾ?????أ?????????????ʾ
********************************************************/
void CFighterDlg::OnMenuShow() 
{
	// TODO: Add your command handler code here
	if(m_bShow)
		ShowWindow(SW_HIDE);
	else
		ShowWindow(SW_SHOW);

	m_bShow = !m_bShow;
}

/********************************************************
*????˵????????????ҳ
*??IE???????
********************************************************/
void CFighterDlg::OnMenuHomepage() 
{
	// TODO: Add your command handler code here
    ShellExecute(NULL, _T("open"), "http://xiaogi.diy.163.com", NULL, NULL, SW_MAXIMIZE);
}

void CFighterDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
	NOTIFYICONDATA tnid;
	
	tnid.cbSize=sizeof(NOTIFYICONDATA);
	tnid.hWnd=this->m_hWnd;
	tnid.uID=IDR_MAINFRAME;//??֤ɾ?????????ǵ?ͼ??

	Shell_NotifyIcon(NIM_DELETE,&tnid);
}

void CFighterDlg::OnMenuLoad() 
{
	// TODO: Add your command handler code here
	OnButtonLoad();
}

void CFighterDlg::OnMenuQuit() 
{
	// TODO: Add your command handler code here
	OnButtonQuit();
}

void CFighterDlg::OnMenuSave() 
{
	// TODO: Add your command handler code here
	OnButtonSave();
}

void CFighterDlg::OnMenuSound() 
{
	// TODO: Add your command handler code here
	m_bSound = !m_bSound;
}
/*
void CFighterDlg::LoadJPG(CString filename)
{
	BYTE *tmp;
	tmp=JpegFile::JpegFileToRGB(filename, &m_nJPGWidth, &m_nJPGHeight);
	if (tmp==NULL) {
//		AfxMessageBox(IDS_LOADFRAME_ERROR);
		PostQuitMessage(0);
		return;
	}

	// m_buf is the global buffer
	if (m_pJPGBuf!=NULL) {
		delete [] m_pJPGBuf;
		m_pJPGBuf=NULL;
	}

	// do this before DWORD-alignment!!!
	// this works on packed (not DWORD-aligned) buffers
	// swap red and blue for display
	JpegFile::BGRFromRGB(tmp, m_nJPGWidth, m_nJPGHeight);

	// DWORD-align for display
	UINT nWidthDW;
	m_pJPGBuf = JpegFile::MakeDwordAlignedBuf(tmp,
									 m_nJPGWidth,
									 m_nJPGHeight,
									 &nWidthDW);

	delete [] tmp;

	// vertical flip for display
	JpegFile::VertFlipBuf(m_pJPGBuf, nWidthDW, m_nJPGHeight);
}

void CFighterDlg::ShowJPG(CDC *pDC)
{
	if(m_pJPGBuf==NULL)
		return;
	CRect clientRect;
	GetClientRect(clientRect);

	// Center It
	UINT left = (clientRect.Width() - m_nJPGWidth) / 2;
	UINT top = (clientRect.Height() - m_nJPGHeight) / 2;

	BITMAPINFOHEADER bmiHeader;
	bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmiHeader.biWidth = m_nJPGWidth;
	bmiHeader.biHeight = m_nJPGHeight;
	bmiHeader.biPlanes = 1;
	bmiHeader.biBitCount = 24;
	bmiHeader.biCompression = BI_RGB;
	bmiHeader.biSizeImage = 0;
	bmiHeader.biXPelsPerMeter = 0;
	bmiHeader.biYPelsPerMeter = 0;
	bmiHeader.biClrUsed = 0;
	bmiHeader.biClrImportant = 0;


	// now blast it to the CDC passed in.
	// lines returns the number of lines actually displayed
	int lines = StretchDIBits(pDC->m_hDC,
				left, top,
				bmiHeader.biWidth,
				bmiHeader.biHeight,
				0,0,
				bmiHeader.biWidth,
				bmiHeader.biHeight,
				m_pJPGBuf,
				(LPBITMAPINFO)&bmiHeader,
				DIB_RGB_COLORS,
				SRCCOPY);

}
*/

void CFighterDlg::OnButtonNew() 
{
	// TODO: Add your control notification handler code here
	if(m_nGameStatus==FIGHTER_POSITION)
	{
		CFighterInfo fighter;
		for(int i=0; i<10; i++)
		{
			for(int j=0; j<10; j++)
			{
				if(m_nShootingResult[i][j] == FIGHTER_POSITION_NULL)
					fighter.m_nSky[i][j] = FIGHTER_NULL;
				else if(m_nShootingResult[i][j] == FIGHTER_POSITION_BODY)
					fighter.m_nSky[i][j] = FIGHTER_BODY;
				else
					fighter.m_nSky[i][j] = FIGHTER_HEAD;
				TRACE("%d, ", m_nShootingResult[i][j]);
			}
			TRACE("\n");
		}
		if(!fighter.IsSkyValid())
		{
			AfxMessageBox("???ֲ???ȷ???????²??֡?");
			return;
		}
		for(int k=0; k<10; k++)
			for(int l=0; l<10; l++)
			{
				m_nSky[k][l] = fighter.m_nSky[k][l];
				m_nShootingResult[k][l] = 0;
			}
	}
	else
	{
		if(m_nGameStatus == FIGHTER_RUNNING)
		{
			if(MessageBox("??Ϸ?????С???Ҫ???¿?ʼ??", "??ɻ?????????",MB_YESNO)!=IDYES)
				return;
		}
		for(int i=0; i<10; i++)
			for(int j=0; j<10; j++)
			{
				m_nShootingResult[i][j] = 0;
				m_nSky[i][j] = 0;
			}

		for(i=0; i<3; i++){
			CFighterInfo fighter;
			for(int k=0; k<10; k++)
				for(int l=0; l<10; l++)
					fighter.m_nSky[k][l] = m_nSky[k][l];
			do{
				fighter.SetHeadPos(CPoint(GetRand_10(), GetRand_10()));
				fighter.SetFighterPosition(GetRand_4());
			}while(!fighter.IsFighterValid());
			fighter.SetItInSky();
			for(k=0; k<10; k++)
				for(int l=0; l<10; l++)
					m_nSky[k][l] = fighter.m_nSky[k][l];
		}
	}

	m_nFighterDown = 0;
	m_nFighterHit = 0;
	m_nBomb = 0;

	if(m_nWelcomeTimer)
	{
		KillTimer(m_nWelcomeTimer);
		m_nWelcomeTimer = 0;
	}	

	m_strComment1 = "";
	m_strComment2 = "";
	m_strComment3 = "";
	m_strComment4 = "??ע??";
	m_strComment5 = "??Ϸ??ʼ";

	m_ptComment.y = m_rectCommentFrame.top;

	m_nGameStatus = FIGHTER_RUNNING;

	if(!m_nCommentTimer)
	{
		KillTimer(m_nCommentTimer);
		m_nCommentTimer = SetTimer(FIGHTER_COMMENT_TIMER, FIGHTER_SCRROLTIME, NULL);
	}
	InvalidateRect(m_rectSky, TRUE);
}

void CFighterDlg::OnButtonLoad() 
{
	// TODO: Add your control notification handler code here
	if(m_nGameStatus == FIGHTER_RUNNING)
	{
		if(MessageBox("??Ϸ?????С???Ҫ??????һ??Ϸ??", "??ɻ?????????", MB_OKCANCEL)==IDCANCEL)
			return;
	}

	CFileDialog dlgFile(
		TRUE, _T("*.pos"), NULL,
		OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
		_T("?????ļ?(*.pos)|*.pos||"));

	if (dlgFile.DoModal() == IDCANCEL)
		return ;

	CString sPath = dlgFile.GetPathName();
	CString sExt = dlgFile.GetFileExt();
	sExt.MakeLower();
	if(sExt != "pos")
	{
		AfxMessageBox("??ѡ??pos?ļ???");
		return;
	}

	CFile file;
	if(file.Open((LPCTSTR)sPath, CFile::modeRead)==FALSE)
	{
		AfxMessageBox("??pos?ļ?ʧ?ܣ?");
		return;
	}

	SAVEPOSITION data;
	if(file.Read(&data, sizeof(SAVEPOSITION))==0)
	{
		AfxMessageBox("????pos?ļ?ʧ?ܣ?");
		return;
	}

	file.Close();

	for(int i=0; i<10; i++)
		for(int j=0; j<10; j++)
		{
			if(data.nSky[i][j]<0 || data.nSky[i][j]>2)
			{
				AfxMessageBox("Error: the load file may be corrupted");
				return;
			}
			m_nSky[i][j] = data.nSky[i][j];
		}


	m_ptComment.y = m_rectCommentFrame.top;
	m_strComment1 = m_strComment3;
	m_strComment2 = m_strComment4;
	m_strComment3 = m_strComment5;
	m_strComment4 = "?????ļ???...";
	m_strComment5 = "????ɹ???";
	if(!m_nCommentTimer)
	{
		KillTimer(m_nCommentTimer);
		m_nCommentTimer = SetTimer(FIGHTER_COMMENT_TIMER, FIGHTER_SCRROLTIME, NULL);
	}

	for(i=0; i<10; i++)
		for(int j=0; j<10; j++)
			m_nShootingResult[i][j] = 0;

	m_nFighterDown = 0;
	m_nFighterHit = 0;
	m_nBomb = 0;

	if(m_nWelcomeTimer)
	{
		KillTimer(m_nWelcomeTimer);
		m_nWelcomeTimer = 0;
	}	

	m_nGameStatus = FIGHTER_RUNNING;

	InvalidateRect(m_rectSky, FALSE);
	InvalidateRect(m_rectCommentFrame, FALSE);
}

void CFighterDlg::OnButtonOption() 
{
	// TODO: Add your control notification handler code here
	CPropertySheet Sheet("ѡ??", this, 0);

	CRankPage rankPage;
	for(int i=0; i<10; i++)
	{
		rankPage.m_fHitPercentage[i] = m_TopTen.hitpercentage[i];
		rankPage.m_nBomb[i] = m_TopTen.bomb[i];
		sprintf(rankPage.m_strName[i], "%s", m_TopTen.name[i]);
	}

	CAboutPage aboutPage;
	COperationPage operationPage;
	CSettingPage settingPage;
	settingPage.m_strBossFile = m_strBossFile;

	Sheet.m_psh.dwFlags &= ~PSH_HASHELP;
	Sheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;

	Sheet.AddPage(&settingPage);
	Sheet.AddPage(&rankPage);
	Sheet.AddPage(&operationPage);
	Sheet.AddPage(&aboutPage);

	if(Sheet.DoModal()==IDOK)
	{
		m_strBossFile = settingPage.m_strBossFile;
		m_bSound = settingPage.m_bSound;

		if(settingPage.m_bShortcut)
		{
			CString strShortcutText;
			strShortcutText = settingPage.m_strShortcutName;

			char pathname[_MAX_PATH];
			GetModuleFileName(NULL, pathname, _MAX_PATH);//??ִ???ļ?????Ŀ¼

			char winpath[_MAX_PATH];
			::GetWindowsDirectory(winpath, _MAX_PATH);
			CString destPath = winpath;
			destPath += "\\Desktop\\";
			destPath += (strShortcutText.Right(4)==".lnk")?(strShortcutText):(strShortcutText+".lnk");

			FileLink(pathname, (LPCTSTR)destPath);
		}
	}
}

void CFighterDlg::OnButtonPosition() 
{
	// TODO: Add your control notification handler code here
	if(m_nGameStatus == FIGHTER_RUNNING)
	{
		if(MessageBox("??Ϸ?????С???Ҫ?????ֶ???????", "??ɻ?????????", MB_OKCANCEL)==IDCANCEL)
			return;
	}

	m_nGameStatus = FIGHTER_POSITION;
	m_bByComputer = FALSE;

	for(int i=0; i<10; i++)
		for(int j=0; j<10; j++)
			m_nShootingResult[i][j] = FIGHTER_POSITION_NULL;

	m_strComment1 = "";
	m_strComment2 = "";
	m_strComment3 = "";
	m_strComment4 = "?ֶ????ֿ?ʼ";
	m_strComment5 = "???ס???ֹ???";

	if(m_nWelcomeTimer)
	{
		KillTimer(m_nWelcomeTimer);
		m_nWelcomeTimer = 0;
	}	

	if(!m_nCommentTimer)
		KillTimer(m_nCommentTimer);
	m_nCommentTimer = SetTimer(FIGHTER_COMMENT_TIMER, FIGHTER_SCRROLTIME, NULL);

	InvalidateRect(m_rectSky, FALSE);
}

void CFighterDlg::OnButtonQuit() 
{
	// TODO: Add your control notification handler code here
	CQuitDlg dlg;
	if(dlg.DoModal()==IDCANCEL)
		return;
	SendMessage(WM_CLOSE);
}

void CFighterDlg::OnButtonSave() 
{
	// TODO: Add your control notification handler code here
	if(m_nGameStatus==FIGHTER_POSITION)
	{
		CFighterInfo fighter;
		for(int i=0; i<10; i++)
			for(int j=0; j<10; j++)
			{
				if(m_nShootingResult[i][j] == FIGHTER_POSITION_NULL)
					fighter.m_nSky[i][j] = FIGHTER_NULL;
				else if(m_nShootingResult[i][j] == FIGHTER_POSITION_BODY)
					fighter.m_nSky[i][j] = FIGHTER_BODY;
				else
					fighter.m_nSky[i][j] = FIGHTER_HEAD;
			}
		if(!fighter.IsSkyValid())
		{
			AfxMessageBox("???ֲ???ȷ???????²??֡?");
			return;
		}
		for(int k=0; k<10; k++)
			for(int l=0; l<10; l++)
				m_nSky[k][l] = fighter.m_nSky[k][l];
	}

	BOOL bSkyNULL = TRUE;
	for(int i=0; i<10; i++)
		for(int j=0; j<10; j++)
			if(m_nSky[i][j]!=0)bSkyNULL=FALSE;
	if(bSkyNULL)
	{
		AfxMessageBox("??Ϸ??δ??ʼ?????ȵ????????Ϸ??");
		return;
	}

	CFileDialog dlgFile(
		FALSE, _T("*.pos"), NULL,
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		_T("?????ļ?(*.pos)|*.pos||"));

	if (dlgFile.DoModal() == IDCANCEL)
		return ;

	CString sPath = dlgFile.GetPathName();

	CFile file;
	if(file.Open((LPCTSTR)sPath, CFile::modeCreate|CFile::modeWrite)==FALSE)
	{
		AfxMessageBox("??pos?ļ?ʧ?ܣ?");
		return;
	}

	SAVEPOSITION data;
	data.dwVersion = 0x00000100;

	for(i=0; i<10; i++)
		for(int j=0; j<10; j++)
			data.nSky[i][j] = m_nSky[i][j];

	file.Write(&data, sizeof(SAVEPOSITION));

	file.Close();

	m_ptComment.y = m_rectCommentFrame.top;
	m_strComment1 = m_strComment3;
	m_strComment2 = m_strComment4;
	m_strComment3 = m_strComment5;
	m_strComment4 = "?????ļ???...";
	m_strComment5 = "????ɹ???";
	if(!m_nCommentTimer)
	{
		KillTimer(m_nCommentTimer);
		m_nCommentTimer = SetTimer(FIGHTER_COMMENT_TIMER, FIGHTER_SCRROLTIME, NULL);
	}
}